home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 4 / ETO Development Tools 4.iso / Essentials / MacApp Documentation / MacApp.TECH$ Archives / 1991 / Feb 91 / MacApp.Tech$ 2⁄8⁄91 / 2838-Re Dynamic Arrays in-Feb91 < prev    next >
Encoding:
Text File  |  1991-03-06  |  6.3 KB  |  286 lines  |  [TEXT/GEOL]

  1. Item    0789348                         2-Feb-91        18:32PST
  2.  
  3. From:   AUST0363                        AUDev - Repertoire Pty Ltd, SA,IDV
  4.  
  5. To:     PEMD                            CH DEV PEMD Group, Zurich,IDV
  6.         MACAPP.TECH$                    MacApp Technical
  7.  
  8. ------------------------------------------------------------------------------
  9.  
  10. Sub:    Re: Dynamic Arrays in Pascal?
  11.  
  12. Earnie,
  13.         Your best bet (and the one that I use all the time) is to declare a
  14. handle to the array and then resize the array dynamically (as suggested by
  15. Bruce).  I embedd this in an object that mimics array functionality (but
  16. without the TList ability to delete/insert while doing an Each).  I have
  17. written an MPW tool that takes a resource description of the type of data that
  18. the list should hold and what kind of operations should be included (e.g. Find
  19. methods that search for particular subcomponents of the usually compound-record
  20. data) and generates the entire unit.  The beauty of doing this is that you can
  21. included it in your make file to regenerate as neccessary (i.e. when the list
  22. definition or implementation changes).  Also you can write a cool front end to
  23. edit the resources that are fed in.  For example the following is the resource
  24. and some output of the tool for a resource list that I generated.  It will show
  25. you what I am talking about, as well as the kind of interface I would
  26. recommend.  I would also recommend Jeffs suggestion of keeping strings in
  27. seperate storage.  Usually strings have different allocation dynamics than
  28. general handles and you can optimize the memory management of them yourself,
  29. especially strings that for e.g. are read in and not changed.
  30.  
  31. Anyway, the example is.
  32.  
  33. Resource input. (Needless to say I also have a tool to convert between pure
  34. code text and Rez format strings)
  35.  
  36. resource 'CGEN' (0, "TResTypeList") {
  37.    RecordList{
  38.    "ResTypeList", "ResTypeRec",
  39.    {
  40.    Uses {{ "Resources" }},
  41.  
  42.    Types {{
  43.    "ResTypeRec = record",
  44.    "   fResType: ResType;",
  45.    "   fCount  : integer;",
  46.    "   fView   : TView;",
  47.    "end;"
  48.    }},
  49.  
  50.    FindMethods {
  51.    kMTFind,
  52.    "",
  53.    { "ResType" },
  54.    {
  55.    "begin",
  56.    "   TestProc := fData [index].fResType = key1;",
  57.    "end;"
  58.    }
  59.    },
  60.  
  61.    FindMethods {
  62.    kMTFindNth + kMTCountOf,
  63.    "NonZeroType",
  64.    { },
  65.    {
  66.    "begin",
  67.    "   TestProc := fData [index].fCount <> 0;",
  68.    "end;"
  69.    }
  70.    },
  71.  
  72.    DynamicFields {{
  73.    "Var",
  74.    "   result  : Str255;",
  75.    "   resCountString  : Str255;",
  76.    "",
  77.    "begin",
  78.    "   result [0] := Chr (4);",
  79.    "   result [1] := theData.fResType [1];",
  80.    "   result [2] := theData.fResType [2];",
  81.    "   result [3] := theData.fResType [3];",
  82.    "   result [4] := theData.fResType [4];",
  83.    "   NumToString (theData.fCount, resCountString);",
  84.    "   result := Concat (result, ' ', resCountString);",
  85.    "   DoToField (indexString, @result, bString);",
  86.    "   DoToField (Concat (indexString, '.fView'), @theData.fView, bObject);",
  87.    "end;"
  88.    }}
  89.    }
  90.    }
  91. };
  92.  
  93. Some output.
  94.  
  95. Unit UResTypeList;
  96.  
  97. INTERFACE
  98.  
  99.    Uses
  100.    { • MacApp }
  101.    UMacApp
  102.  
  103.    { • Building Blocks }
  104.  
  105.    { • Interface }
  106.    , UUndoingObject
  107.  
  108.    { • Implementation }
  109.    , Resources
  110.    , Packages
  111.    , Types
  112.    ;
  113.  
  114.  
  115.    Type
  116.  
  117.  
  118.    ResTypeRec = record
  119.    fResType: ResType;
  120.    fCount  : integer;
  121.    fView   : TView;
  122.    end;
  123.  
  124.  
  125.    Type
  126.  
  127.  
  128.    TResTypeList = Object (TUndoingObject)
  129.  
  130.  
  131.    fSize   : integer;
  132.    fMaxSize: integer;
  133.    fData   : array [1..1] of ResTypeRec;
  134.  
  135.  
  136.    Procedure TResTypeList.IResTypeRecList;
  137.  
  138.    Procedure TResTypeList.Compress;
  139.  
  140.    Procedure TResTypeList.SetSize
  141.    (theSize : integer);
  142.  
  143.    Function TResTypeList.At
  144.    (index : integer) : ResTypeRec;
  145.  
  146.    Procedure TResTypeList.AtPut
  147.    (index  : integer;
  148.     theData: ResTypeRec);
  149.  
  150.    Procedure TResTypeList.InsertBefore
  151.    (theData: ResTypeRec;
  152.     index  : integer);
  153.  
  154.    Procedure TResTypeList.InsertLast
  155.    (theData : ResTypeRec);
  156.  
  157.    Procedure TResTypeList.Delete
  158.    (index : integer);
  159.  
  160.    Procedure TResTypeList.DeleteAll;
  161.  
  162.    Function TResTypeList.FirstThat
  163.    (Function TestItem
  164.    (index : integer) : boolean) : integer;
  165.  
  166.    Function TResTypeList.NthThat
  167.    (n : integer;
  168.     Function TestItem
  169.    (index : integer) : boolean) : integer;
  170.  
  171.    Function TResTypeList.CountOf
  172.    (Function TestItem
  173.    (index : integer) : boolean) : integer;
  174.  
  175.    (*
  176.    Function TResTypeList.SortBy
  177.    (Function CompareItems
  178.    (index1 : integer;
  179.     index2 : integer) : boolean);
  180.    *)
  181.  
  182.    Function TResTypeList.Find
  183.    (Key1 : ResType) : integer;
  184.  
  185.    Function TResTypeList.FindNthNonZeroType
  186.    (index : integer) : integer;
  187.  
  188.    Function TResTypeList.CountOfNonZeroType : integer;
  189.  
  190.    Procedure TResTypeList.Fields
  191.    (Procedure DoToField
  192.    (fieldName  : Str255;
  193.     fieldAddr  : Ptr;
  194.     fieldType  : integer)); Override;
  195.  
  196.    Procedure TResTypeList.DynamicFields
  197.    (Procedure DoToField
  198.    (fieldName  : Str255;
  199.     fieldAddr  : Ptr;
  200.     fieldType  : integer)); Override;
  201.  
  202.    end;
  203.  
  204.  
  205.    Function NewResTypeList : TResTypeList;
  206.  
  207.  
  208. IMPLEMENTATION
  209.  
  210.  
  211. Const
  212.  
  213.    kIncrement  = 4;
  214.    kBaseSelfSize   = 12;
  215.  
  216.  
  217. Function NewResTypeList : TResTypeList;
  218. {——————————————————————————————————}
  219. Var
  220.    aResTypeRecList : TResTypeList;
  221.  
  222. begin
  223.    New (aResTypeRecList);
  224.    FailNil (aResTypeRecList);
  225.    aResTypeRecList.IResTypeRecList;
  226.    NewResTypeList := aResTypeRecList;
  227. end;
  228.  
  229.  
  230. Procedure TResTypeList.IResTypeRecList;
  231. {———————————————————————————————————————}
  232.  
  233. begin
  234.    fSize := 0;
  235.    fMaxSize := 1;
  236.    IUndoingObject;
  237. end;
  238.  
  239.  
  240. Procedure TResTypeList.Compress;
  241. {———————————————————————————————}
  242.  
  243. begin
  244.    if fMaxSize <> fSize then
  245.    SetHandleSize (Handle (self),
  246.       kBaseSelfSize + fSize * sizeof (ResTypeRec));
  247.    fMaxSize := fSize;
  248. end;
  249.  
  250.  
  251. Procedure TResTypeList.SetSize
  252.    (theSize: integer);
  253. {——————————————————————————————}
  254.  
  255. begin
  256.    theSize := ((theSize - 1) div kIncrement + 1) * kIncrement;
  257.    if fSize < theSize then
  258.    if fMaxSize <> theSize then begin
  259.    SetHandleSize (Handle (self),
  260.       kBaseSelfSize + fMaxSize * sizeof (ResTypeRec));
  261.    FailMemError;
  262.    end;
  263. end;
  264.  
  265.  
  266. Function TResTypeList.At
  267.    (index : integer) : ResTypeRec;
  268. {————————————————————————————}
  269.  
  270. begin
  271.    {$IFC qDebug}
  272.    if (index <= 0) | (fSize < index) then begin
  273.    Writeln ('fSize = ', fSize : 1, '  index = ', index : 1);
  274.    ProgramBreak ('Range Check in TResTypeList.At');
  275.    end;
  276.    {$ENDC}
  277.  
  278.    {$PUSH}
  279.    {$R-}
  280.    At := fData [index];
  281.    {$POP}
  282. end;
  283.  
  284. etc……
  285.  
  286.